module Control_MEM(
    input [1:0]  wd_sel,
    input [31:0] rD2,
    input [31:0] dram_rd,
    input [3:0] load_sel,
    input [2:0] store_sel,
    input [1:0] offset,
    input [31:0] wD,
    output reg [31:0] wD_out,
    output [31:0] wdin
    );
    
    // load_sel
    parameter load_lw =  3'b000;
    parameter load_lh =  3'b001;
    parameter load_lb =  3'b010;
    parameter load_lhu=  3'b011;
    parameter load_lbu=  3'b100;

    // store signal
    parameter store_sw = 2'b00;
    parameter store_sh = 2'b01;
    parameter store_sb = 2'b10;

    always @ (*) begin
        if(wd_sel == 2'b01) begin
                if (load_sel == load_lb) begin
                    case(offset) 
                        2'b00: wD_out = { {24{dram_rd[7]}}  , dram_rd[7:0]  };    
                        2'b01: wD_out = { {24{dram_rd[15]}} , dram_rd[15:8] };    
                        2'b10: wD_out = { {24{dram_rd[23]}} , dram_rd[23:16]};    
                        2'b11: wD_out = { {24{dram_rd[31]}} , dram_rd[31:24]}; 
                        default: wD_out = 32'b0;   
                    endcase
                end                     
                else if(load_sel == load_lh) begin
                    case(offset)
                        2'b00: wD_out = { {16{dram_rd[15]}} , dram_rd[15:0] };      
                        2'b10: wD_out = { {16{dram_rd[31]}} , dram_rd[31:16]}; 
                        default: wD_out = 32'b0;  
                    endcase
                end     
                else if(load_sel == load_lbu) begin
                    case(offset)
                        2'b00: wD_out = { 24'b0 , dram_rd[7:0]  };    
                        2'b01: wD_out = { 24'b0 , dram_rd[15:8] };    
                        2'b10: wD_out = { 24'b0 , dram_rd[23:16]};    
                        2'b11: wD_out = { 24'b0 , dram_rd[31:24]};
                        default: wD_out = 32'b0; 
                    endcase
                end
                else if(load_sel == load_lhu) begin
                    case(offset)
                        2'b00: wD_out = { 16'b0 , dram_rd[15:0] };      
                        2'b10: wD_out = { 16'b0 , dram_rd[31:16]}; 
                        default: wD_out = 32'b0;  
                    endcase
                end
                else if(load_sel == load_lw)      wD_out = dram_rd;
        end 
        else                wD_out = wD;
    end
    

    reg [31:0] rD2_t;
    assign wdin = rD2_t;

    // rD2 control
    always@(*)begin
        case(store_sel)
            store_sb: begin
                case(offset)
                    2'b00: rD2_t = {dram_rd[31:8],rD2[7:0]};
                    2'b01: rD2_t = {dram_rd[31:16],rD2[7:0],dram_rd[7:0]};
                    2'b10: rD2_t = {dram_rd[31:24],rD2[7:0],dram_rd[15:0]};
                    2'b11: rD2_t = {rD2[7:0],dram_rd[23:0]};
                    default: rD2_t = 32'b0;
                endcase
            end
            store_sh: begin
                case(offset)
                    2'b00: rD2_t = {dram_rd[31:16],rD2[15:0]};
                    2'b10: rD2_t = {rD2[15:0],dram_rd[15:0]};
                    default: rD2_t = 32'b0;
                endcase
            end
            store_sw: rD2_t = rD2;
            default : rD2_t = rD2;
        endcase
    end

endmodule
